package proxy

import (
	"context"
	"errors"
	"net/http"

	"gitee.com/les49/esgo/utils"
	"github.com/zeromicro/go-zero/core/breaker"
	"github.com/zeromicro/go-zero/rest/httpc"
)

const (
	CLIENT_NODE_STATUS_OK   = 0
	CLIENT_NODE_STATUS_FAIL = 1
)

type clientNode struct {
	api string
	brk breaker.Breaker
}

type HttpProxy struct {
	nodes map[string]*clientNode
}

func (hp *HttpProxy) addNode(key, api string) error {

	if !utils.IsValidAPI(api) {
		return errors.New("invaild url")
	}

	node := clientNode{
		api: api,
		brk: breaker.NewBreaker(),
	}
	hp.nodes[key] = &node
	return nil
}

func NewHttpProxy() *HttpProxy {
	hp := &HttpProxy{
		nodes: make(map[string]*clientNode, 32),
	}

	return hp
}

func (hp *HttpProxy) SendData(key, api string, data interface{}) error {
	if _, ok := hp.nodes[key]; !ok {
		if err := hp.addNode(key, api); err != nil {
			return err
		}
	}

	_, err := hp.nodes[key].brk.Allow()
	if err != nil {
		return err
	}

	go func() {
		hp.nodes[key].brk.Do(func() error {
			resp, err := httpc.Do(context.Background(), http.MethodPost, hp.nodes[key].api, data)
			if err != nil {
				return breaker.ErrServiceUnavailable
			}
			if resp.StatusCode != 200 {
				return breaker.ErrServiceUnavailable
			}
			return nil
			// return breaker.ErrServiceUnavailable
		})
	}()

	return nil
}
